//    Copyright (C) Kherty.  All rights reserved.
#region

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;

#endregion

namespace OpenLS.UI
{
    [TemplatePart(Type = typeof (Popup), Name = "PART_Popup")]
    public class Gallery : ListBox
    {
        private static readonly GroupStyle defaultGroupStyle = CreateDefaultGroupStyle();

        public static readonly DependencyProperty DropDownHeightProperty =
            DependencyProperty.Register("DropDownHeight", typeof (double), typeof (Gallery),
                                        new UIPropertyMetadata(300.0));

        public static readonly DependencyProperty DropDownWidthProperty =
            DependencyProperty.Register("DropDownWidth", typeof (double), typeof (Gallery),
                                        new UIPropertyMetadata(300.0));

        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register("Header", typeof (object), typeof (Gallery), new UIPropertyMetadata(null));

        public static readonly DependencyProperty IconProperty = RibbonElement.IconProperty.AddOwner(typeof (Gallery));

        // Using a DependencyProperty as the backing store for IsOpen.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsOpenProperty =
            DependencyProperty.Register("IsOpen", typeof (bool), typeof (Gallery),
                                        new UIPropertyMetadata(false, SOnIsOpenChanged));

        // Using a DependencyProperty as the backing store for IsSmallMyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsCollapsedProperty =
            DependencyProperty.Register("IsCollapsed", typeof (bool), typeof (Gallery),
                                        new UIPropertyMetadata(false, sOnIsSmallChanged));

        public static readonly DependencyProperty MaxColumnsProperty =
            GalleryElement.MaxColumnsProperty.AddOwner(typeof (Gallery));

        public Gallery()
        {
            DefaultStyleKey = typeof (Gallery);
        }

        public bool IsOpen
        {
            get { return (bool) GetValue(IsOpenProperty); }
            set { SetValue(IsOpenProperty, value); }
        }

        public bool IsCollapsed
        {
            get { return (bool) GetValue(IsCollapsedProperty); }
            set { SetValue(IsCollapsedProperty, value); }
        }


        public double DropDownWidth
        {
            get { return (double) GetValue(DropDownWidthProperty); }
            set { SetValue(DropDownWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DropDownWidth.  This enables animation, styling, binding, etc...


        public double DropDownHeight
        {
            get { return (double) GetValue(DropDownHeightProperty); }
            set { SetValue(DropDownHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DropDownHeight.  This enables animation, styling, binding, etc...


        public int MaxColumns
        {
            get { return (int) GetValue(MaxColumnsProperty); }
            set { SetValue(MaxColumnsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...


        public object Header
        {
            get { return GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Header.  This enables animation, styling, binding, etc...


        public object Icon
        {
            get { return GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        private void restorePreviousFocus()
        {
            if (IsKeyboardFocusWithin)
            {
                Keyboard.Focus(null);
            }
            var parent = Parent;
            if (parent != null)
            {
                var focusScope = FocusManager.GetFocusScope(parent);
                if (focusScope != null)
                {
                    var focusedElement = FocusManager.GetFocusedElement(focusScope);
                    if (elementIsWithin(focusedElement))
                    {
                        FocusManager.SetFocusedElement(focusScope, null);
                    }
                }
            }
        }

        private bool elementIsWithin(IInputElement element)
        {
            DependencyObject parent;
            if (element == this)
            {
                return true;
            }
            for (var item = element as GalleryItem; item != null; item = parent as GalleryItem)
            {
                parent = item.Parent;
                if (parent == null)
                {
                    parent = ItemsControlFromItemContainer(item);
                }
                if (parent == this)
                {
                    return true;
                }
            }
            return false;
        }


        protected override DependencyObject GetContainerForItemOverride()
        {
            return new GalleryItem();
        }

        private static GroupStyle CreateDefaultGroupStyle()
        {
            var result = new GroupStyle();
            result.HidesIfEmpty = false;
            var template = new HierarchicalDataTemplate(typeof (CollectionViewGroup));
            var border = new FrameworkElementFactory(typeof (Border));
            border.SetValue(Border.BorderBrushProperty, new SolidColorBrush(Color.FromArgb(0xFF, 0xC5, 0xC5, 0xC5)));
            border.SetValue(Border.BorderThicknessProperty, new Thickness(0, 0, 0, 1));
            var textBlock = new FrameworkElementFactory(typeof (TextBlock));

            textBlock.SetBinding(TextBlock.TextProperty, new Binding("Name"));
            textBlock.SetValue(TextBlock.FontWeightProperty, FontWeights.Bold);
            textBlock.SetValue(TextBlock.BackgroundProperty, new SolidColorBrush(Color.FromArgb(0xFF, 0xDD, 0xE7, 0xEE)));
            border.AppendChild(textBlock);
            template.VisualTree = border;
            result.HeaderTemplate = template;
            return result;
        }

        private static void SOnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var b = (bool) e.NewValue;
            var gallery = (Gallery) d;
            if (!b)
                gallery.restorePreviousFocus();
            gallery.setGrouping(b);
        }

        private void setGrouping(bool b)
        {
            if (ItemsSource is ListCollectionView)
            {
                if (b)
                {
                    foreach (var style in GroupStyle)
                    {
                        if (style == defaultGroupStyle)
                            return;
                    }
                    GroupStyle.Add(defaultGroupStyle);
                }
                else
                {
                    GroupStyle.Remove(defaultGroupStyle);
                }
            }
        }

        private static void sOnIsSmallChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var b = (bool) e.NewValue;
            var gallery = (Gallery) d;
            gallery.setGrouping(b);
        }

        // Using a DependencyProperty as the backing store for Icon.  This enables animation, styling, binding, etc...
        //DependencyProperty.Register("Icon", typeof(object), typeof(Gallery), new UIPropertyMetadata(null));
    }
}